package com.yiboshi.rehrs.util;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class AperStringUtils {
    public static boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("win");


    public static Random getRandom(){
        Random random = new Random();

        return random;
    }

    //概率匹配 max=3表示3分之1
    public static boolean hitNumber(int max){
        if(max<=1){
            return true;
        }
        return getRandom().nextInt(max)%max==0;
    }


    public static boolean containsChinese(String str) {
        return str.matches(".*[\u4e00-\u9fa5]+.*");
    }


    public static String removeProtocolHost(String link) {
        if(!link.startsWith("http")){
            return link;
        }
        String protocolHost = AperStringUtils.getProtocolHost(link);
        return link.replaceAll(protocolHost, "");
    }

    public static String getProtocolHost(String link) {
        if (!link.startsWith("http")) {
            return "";
        }
        URL url;
        String host = "";
        try {
            url = new URL(link);
            host = url.getProtocol() + "://" + url.getHost();
            int port = url.getPort();
            if (port != 443 && port != 80 && port > 0) {
                host = host + ":" + port;
            }
        } catch (MalformedURLException e) {
        }
        return host;
    }


    //https://raw.fgit.ml/mmmtoto/tv/main/91mv(219).apk
    static String[] proxyHosts = new String[]{
            "https://ghproxy.com/"
            ,"https://hub.gitmirror.com/"
            ,"https://gh.con.sh/"
            ,"https://ghps.cc/"
            //,"https://ghproxy.futils.com/"
            //,"http://ghproxy.tbooks.com.cn/"
            //,"https://gh-proxy.com/"
            //,"https://gh2.yanqishui.work/"
            //,"http://gh.isteed.cc/"
            //,"https://git.yumenaka.net/"
            //,"https://raw.fastgit.org"
            ,"https://cors.isteed.cc/"
            //,"https://jkpxvlgz.fast-github.tk/-----"
            //https://gh.api.99988866.xyz/
    };
//https://ghproxy.com/https://raw.githubusercontent.com/alice-tvt/static-res/main/e4a3/beij.png
    //https://ghproxy.com/https://raw.githubusercontent.com/alice-vvcc/static-res/main/bfc5/91mv(213).apk
    public static String proxyGithubUrl(String githubUrl) {
        if(!githubUrl.contains("githubusercontent")){
            return githubUrl;
        }
        if (githubUrl.contains("proxy")
            ||githubUrl.contains("//gh")
            ||githubUrl.contains("isteed")
                ) {
            return githubUrl;
        }
        int hostIndex = getRandom().nextInt(proxyHosts.length);
        hostIndex = hostIndex<0?-hostIndex:hostIndex;
        String newHost = proxyHosts[hostIndex];
        if(newHost.contains("raw.fastgit")){
            return githubUrl.replaceAll("https://raw.githubusercontent.com",newHost);
        }
        return  newHost+ githubUrl;
    }

    public static String changeHostUrl(String githubUrl, String host) {
        if (StringUtils.isBlank(host) || githubUrl.startsWith(host)) {
            return githubUrl;
        }
        String protocolHost = AperStringUtils.getProtocolHost(githubUrl);
        return githubUrl.replace(protocolHost, host);
    }

    public static String githubCdn(String githubUrl) {
        if (!githubUrl.contains("github")) {
            return githubUrl;
        }
        String protocolHost = AperStringUtils.getProtocolHost(githubUrl);
        if (!protocolHost.contains("github")) {
            return githubUrl;
        }

        githubUrl = githubUrl.replace(protocolHost + "/", "");
        String[] split = githubUrl.split("/");
        String temp = split[0] + "/" + split[1] + "/";
        String newUrl = "/gh/" + githubUrl.replace(temp, split[0] + "/" + split[1] + "@");
        return "https://cdn.jsdelivr.net" + newUrl;
        //return "https://cdn.statically.io" + newUrl;

    }



    public static int randomNum(int max) {
        return getRandom().nextInt(max);
    }


    // 121101 = 121000-122000
    public static String getParentNameById(Long id) {
        Long i = id / 1000;
        return i + "000-" + (i + 1) + "000/" + id + "/";
    }

    public static boolean isEmpty(String ee) {
        return ee == null || ee.length() == 0 || "".equals(ee);
    }

    public static boolean isNotEmpty(String ee) {
        return !isEmpty(ee);
    }

    private static boolean checkIMEI(String imei) {
        return imei.length() >= 15;
		/*
		int even = 0, odd = 0;
		for (int i = 0; i < imei.length(); i++) {
			int me = Integer.parseInt(imei.charAt(i) + "");
			if (i % 2 == 0) {
				even += me;
			} else {
				String tmp = 2 * me + "";
				for (int j = 0; j < tmp.length(); j++) {
					odd += Integer.parseInt(tmp.charAt(j) + "");
				}
			}
		}
		int sum = even + odd;
		return sum % 10 == 0;*/
    }

    public static boolean checkValidIMEI(String imei) {
        try {

            return checkIMEI(imei);
        } catch (Exception e) {
            return false;
        }
    }

    static String base = "123456789ABCDEFGHJKMNPQRSTUVWXYZ".toLowerCase();

    static String baseNum = "0123456789".toLowerCase();

    public static String getRandomNumString(int length) {
        if (length <= 0) {
            return null;
        }
        Random random = getRandom();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(baseNum.length());
            sb.append(baseNum.charAt(number));
        }
        return sb.toString();
    }

    public static String getRandomCodeString(int length) {
        if (length <= 0) {
            return null;
        }
        Random random = getRandom();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }

    public static String getMd5RandomCode(int length) {
        base = "ABCDEFGHJKMNPQRSTUVWXYZ==========================".toLowerCase();
        if (length <= 0) {
            return null;
        }
        Random random =getRandom();
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        return sb.toString();
    }


    public static boolean isNumber(String str) {
        if (isEmpty(str)) {
            return false;
        }
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

    //截取数字
    public static String getNumbers(String content) {
        Pattern pattern = Pattern.compile("[^0-9]");
        Matcher matcher = pattern.matcher(content);
        return matcher.replaceAll("").trim();
    }

    public static boolean isMobileNO(String mobiles) {
        if (isEmpty(mobiles)) {
            return false;
        }
        Pattern p = Pattern.compile("^1[0-9]{10}$");
        Matcher m = p.matcher(mobiles);
        return m.matches();
    }

    public static String escape(String src) {
        int i;
        char j;
        StringBuffer tmp = new StringBuffer();
        tmp.ensureCapacity(src.length() * 6);
        for (i = 0; i < src.length(); i++) {
            j = src.charAt(i);
            if (Character.isDigit(j) || Character.isLowerCase(j)
                    || Character.isUpperCase(j))
                tmp.append(j);
            else if (j < 256) {
                tmp.append("%");
                if (j < 16)
                    tmp.append("0");
                tmp.append(Integer.toString(j, 16));
            } else {
                tmp.append("%u");
                tmp.append(Integer.toString(j, 16));
            }
        }
        return tmp.toString();
    }

    public static String unescape(String src) {
        StringBuffer tmp = new StringBuffer();
        tmp.ensureCapacity(src.length());
        int lastPos = 0, pos = 0;
        char ch;
        while (lastPos < src.length()) {
            pos = src.indexOf("%", lastPos);
            if (pos == lastPos) {
                if (src.charAt(pos + 1) == 'u') {
                    ch = (char) Integer.parseInt(src
                            .substring(pos + 2, pos + 6), 16);
                    tmp.append(ch);
                    lastPos = pos + 6;
                } else {
                    ch = (char) Integer.parseInt(src
                            .substring(pos + 1, pos + 3), 16);
                    tmp.append(ch);
                    lastPos = pos + 3;
                }
            } else {
                if (pos == -1) {
                    tmp.append(src.substring(lastPos));
                    lastPos = src.length();
                } else {
                    tmp.append(src.substring(lastPos, pos));
                    lastPos = pos;
                }
            }
        }
        return tmp.toString();
    }

    /**
     * @param src
     * @return
     * @disc 对字符串重新编码
     */
    public static String isoToGB(String src) {
        String strRet = null;
        try {
            strRet = new String(src.getBytes("ISO_8859_1"), "GB2312");
        } catch (Exception e) {

        }
        return strRet;
    }

    /**
     * @param src
     * @return
     * @disc 对字符串重新编码
     */
    public static String isoToUTF(String src) {
        String strRet = null;
        try {
            strRet = new String(src.getBytes("ISO_8859_1"), "UTF-8");
        } catch (Exception e) {

        }
        return strRet;
    }

    static String regex = "((http[s]{0,1}|ftp)://[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)|((www.)|[a-zA-Z0-9\\.\\-]+\\.([a-zA-Z]{2,4})(:\\d+)?(/[a-zA-Z0-9\\.\\-~!@#$%^&*+?:_/=<>]*)?)";
    static Pattern pattern = Pattern.compile(regex);

    public static boolean matchURL(String url) {
        return pattern.matcher(url).matches();
    }

    public static boolean isChineseName(String realname) {
        return Pattern.matches("[\u4e00-\u9fa5|·]{2,15}", realname);
    }

    public static boolean isValidEnglishWord(String code) {
        return isValidCode(code,1);
    }
    public static boolean isValidCode(String code, int minLength) {
        if (isEmpty(code)) {
            return false;
        }
        if (code.length() < minLength) {
            return false;
        }
        return Pattern.matches("^[a-zA-Z\\+'\\s]+", code);
    }


    public static String signatureByDay(String text){
        return signatureByDay(text,LocalDateTime.now());
    }

    public static String signatureByDay(String text,LocalDateTime dateTime){
        int hour = dateTime.getHour();
        String s = dateTime.toLocalDate().toString();
        if(hour>=12){
            s = s+"12";
        }else{
            s = s+"00";
        }
        return MD5.encode(s+text);
    }

    public static boolean validMd5ByDay(String sign,String text){
        if(isEmpty(sign)){
            return false;
        }
        LocalDateTime dateTime = LocalDateTime.now();
        return sign.equals(signatureByDay(text,dateTime))
                ||sign.equals(signatureByDay(text,dateTime.plusHours(-12)))
                ||sign.equals(signatureByDay(text,dateTime.plusHours(12)))
                ;
    }



    public static String getMetUrl(String href) {
        //log.info("getMetUrl,href={}",href);
        //return href;
        int i = href.indexOf("dn=");
        if (i > 0) {
            href = href.substring(0, i);
        }
        return href.trim();
    }

    //包含数字字母和-
    static String regexMovieCode = "^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*-).+$";
    public static boolean isMovieCode(String string1) {
        if(string1.length()>=18){
            return false;
        }
      return   string1.matches(regexMovieCode);
    }

    public static boolean isMovieZhTitle(String string1) {
        String regex = ".*[\\u4e00-\\u9fa5\\u3040-\\u309f\\u30a0-\\u30ff].*";
        return string1.matches(regex);

    }
static Charset character = Charset.forName("utf-8");

    //x_api_permission = "1"
    //base64(随机一个字符+明文)
    //
    public static String encode(String contentStr){
        String s1 = AperStringUtils.getRandomNumString(1)+ contentStr;
        byte[] bytes = s1.getBytes(character);
        String encode = Base64.encode(bytes);
        int sub = encode.length()/2;
        String substring1 = encode.substring(0, sub);
        String substring2 = encode.substring(encode.length()-sub);
        String s = new StringBuilder(substring2).reverse()+ AperStringUtils.getRandomCodeString(2)
                + new StringBuilder(substring1).reverse();
        return s;
    }


    public static String decode(String decodeCont){
        int length =( decodeCont.length()-2)/2;
        String sub1 = decodeCont.substring(0, length);
        String sub2 = decodeCont.substring(length+2);
        String org = new StringBuilder(sub2).reverse().append(new StringBuilder(sub1).reverse().toString()).toString();
        org = Base64.decodeStr(org);
        org = org.substring(1);
        return org;
    }


    public static void main(String[] args) {
        String abc = generateRandomIdCard();
        System.out.println(abc);
    }


    public static List<Integer> asIntegerList(String str){
        String[] split = str.split(",");
        List<Integer> list = new ArrayList<>();
        for (String s : split) {
            list.add(Integer.valueOf(s));
        }
        return list;
    }

    /**
     * 生成随机中国大陆身份证号码（18位）
     */
    public static String generateRandomIdCard() {
        Random random = getRandom();
        // 1. 地址码（6位）：前两位省份代码(11-65)，后四位随机区县码
        String areaCode = String.format("%02d", 11 + random.nextInt(55)) +
                String.format("%04d", random.nextInt(10000));

        // 2. 出生日期（8位）：1965-01-01 至 当前日期
        long minDay = LocalDate.of(1965, 1, 1).toEpochDay();
        long maxDay = LocalDate.now().plusYears(-18).toEpochDay();
        LocalDate birthDate = LocalDate.ofEpochDay(minDay + random.nextInt((int)(maxDay - minDay)));
        String birthCode = birthDate.format(DateTimeFormatter.ofPattern("yyyyMMdd"));

        // 3. 顺序码（3位）
        String sequenceCode = String.format("%03d", random.nextInt(1000));

        // 4. 组合前17位
        String prefix = areaCode + birthCode + sequenceCode;
        char[] prefixChars = prefix.toCharArray();

        // 5. 计算校验码（第18位）
        int[] weight = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}; // 加权因子
        char[] validateCodes = {'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'}; // 校验码映射

        int sum = 0;
        for (int i = 0; i < 17; i++) {
            sum += (prefixChars[i] - '0') * weight[i];
        }
        char validateCode = validateCodes[sum % 11];

        return prefix + validateCode;
    }






// https://bejav.tv
// https://ggc-fr-2.imcontent.me/30/vod2/3b/97/jkxpr5q2_12a3dc61f80e4742e8d478478eedff049e2fb2555fb5be/720/v.m3u8

}
